using System;
using System.Text;
using System.Text.RegularExpressions;

namespace ICSharpCode.TextEditor.Formatting
{
    public class HtmlFormatStrategy : IFormattingStrategy
    {
        private enum LastTagType
        {
            BeginTag,
            Text,
            EndTag,
            None
        }

        private CssFormatStrategy css = new CssFormatStrategy();

        private JavascriptFormatStrategy js = new JavascriptFormatStrategy();

        private string[] ToFormatArray(string inputString)
        {
            Regex regex = new Regex("[^:]//.+\n", RegexOptions.IgnoreCase);
            Match match = regex.Match(inputString);
            while (match.Success)
            {
                string value = match.Groups[0].Value;
                string newValue = "__comment__" + value.Replace("\r\n", "\n");
                inputString = inputString.Replace(value, newValue);
                match = match.NextMatch();
            }
            StringBuilder stringBuilder = new StringBuilder(inputString);
            StringBuilder stringBuilder2 = new StringBuilder();
            stringBuilder.Replace("\r\n", "");
            stringBuilder.Replace("<", "\n<");
            stringBuilder.Replace(">", ">\n");
            char[] separator = new char[1] { '\n' };
            string[] array = stringBuilder.ToString().Split(separator,StringSplitOptions.RemoveEmptyEntries);
            bool flag = false;
            bool flag2 = true;
           // bool flag3 = false;
           // bool flag4 = true;
            bool flag5 = false;
            bool flag6 = true;
            bool flag7 = false;
            string[] array2 = array;
            foreach (string text in array2)
            {
                string text2 = text.Trim();
                if (string.IsNullOrEmpty(text2))
                {
                    continue;
                }
                if (text2.Equals("<title>", StringComparison.CurrentCultureIgnoreCase))
                {
                    flag = true;
                    flag2 = false;
                }
                if (text2.Equals("</title>", StringComparison.CurrentCultureIgnoreCase))
                {
                    flag = false;
                    flag2 = true;
                }
                if (Regex.IsMatch(text2, "<script.+src=.+>"))
                {
                    flag7 = true;
                    stringBuilder2.Append(text2);
                }
                else if (text2.StartsWith("<script", StringComparison.CurrentCultureIgnoreCase))
                {
                    flag5 = true;
                    flag6 = false;
                    stringBuilder2.Append(text2 + "\n");
                }
                else if (flag5 && !flag6 && text2.IndexOf("<script") == -1 && text2.IndexOf("</script>") == -1)
                {
                    text2 = text2.Replace("__comment__", "__newline__");
                    stringBuilder2.Append(text2);
                    if ((text2 ?? "").IndexOf("//") != -1)
                    {
                        stringBuilder2.Append("__newline__");
                    }
                }
                else if (text2.StartsWith("</script>", StringComparison.CurrentCultureIgnoreCase))
                {
                    flag5 = false;
                    flag6 = true;
                    if (!flag7)
                    {
                        stringBuilder2.Append("\n");
                    }
                    stringBuilder2.Append(text2 + "\n");
                    flag7 = false;
                }
                else if (flag && !flag2)
                {
                    stringBuilder2.Append(text2);
                }
                else
                {
                    stringBuilder2.Append(text2 + "\n");
                }
            }
            return stringBuilder2.ToString().Split(separator,StringSplitOptions.RemoveEmptyEntries);
        }

        private string[] FormatImp(string[] arrayString)
        {
            int num = 4;
            int num2 = 0;
            LastTagType lastTagType = LastTagType.None;
            bool flag = false;
            bool flag2 = true;
            for (int i = 0; i < arrayString.Length; i++)
            {
                if (arrayString[i].Trim().Equals("<head>", StringComparison.CurrentCultureIgnoreCase))
                {
                    flag = true;
                    flag2 = false;
                }
                if (arrayString[i].Trim().Equals("</head>", StringComparison.CurrentCultureIgnoreCase))
                {
                    flag = false;
                    flag2 = true;
                }
                if (Regex.IsMatch(arrayString[i], "<(!DOCTYPE).+>"))
                {
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                }
                else if (Regex.IsMatch(arrayString[i], "<(title).+>"))
                {
                    num2++;
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    num2--;
                }
                else if (Regex.IsMatch(arrayString[i], "<(meta).+>"))
                {
                    num2++;
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    num2--;
                }
                else if (Regex.IsMatch(arrayString[i], "<(link).+>"))
                {
                    if (flag && !flag2)
                    {
                        num2++;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    if (flag && !flag2)
                    {
                        num2--;
                    }
                }
                else if (Regex.IsMatch(arrayString[i], "^<!--.+-->$"))
                {
                    if (flag && !flag2)
                    {
                        num2++;
                        arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                        num2--;
                    }
                    else
                    {
                        arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    }
                }
                else if (Regex.IsMatch(arrayString[i], "<!--\\[if lt IE \\d\\]>"))
                {
                    if (lastTagType == LastTagType.BeginTag)
                    {
                        num2++;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    lastTagType = LastTagType.BeginTag;
                }
                else if (Regex.IsMatch(arrayString[i], "<!--\\[else\\]>"))
                {
                    num2--;
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    num2++;
                }
                else if (Regex.IsMatch(arrayString[i], "<!\\[endif\\]-->"))
                {
                    if (lastTagType == LastTagType.Text || lastTagType == LastTagType.EndTag)
                    {
                        num2--;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    lastTagType = LastTagType.EndTag;
                }
                else if (Regex.IsMatch(arrayString[i], "<script.+src.+></script>"))
                {
                    if (flag && !flag2)
                    {
                        num2++;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    if (flag && !flag2)
                    {
                        num2--;
                    }
                }
                else if (Regex.IsMatch(arrayString[i], "<style.+type=.+>"))
                {
                    if (i < arrayString.Length - 1)
                    {
                        arrayString[i + 1] = "__style__" + arrayString[i + 1];
                    }
                    if (lastTagType == LastTagType.BeginTag)
                    {
                        num2++;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    lastTagType = LastTagType.BeginTag;
                }
                else if (Regex.IsMatch(arrayString[i], "<script.+type=.+>"))
                {
                    if (i < arrayString.Length - 1)
                    {
                        arrayString[i + 1] = "__script__" + arrayString[i + 1];
                    }
                    if (lastTagType == LastTagType.BeginTag)
                    {
                        num2++;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    lastTagType = LastTagType.BeginTag;
                }
                else if (Regex.IsMatch(arrayString[i], "<[^\\/].+/>"))
                {
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                }
                else if (Regex.IsMatch(arrayString[i], "<[^\\/].+>") || Regex.IsMatch(arrayString[i], "<(p|a|h|i)*>"))
                {
                    if (lastTagType == LastTagType.BeginTag)
                    {
                        num2++;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    lastTagType = LastTagType.BeginTag;
                }
                else if (Regex.IsMatch(arrayString[i], "<\\/.+>"))
                {
                    if (lastTagType == LastTagType.Text || lastTagType == LastTagType.EndTag)
                    {
                        num2--;
                    }
                    arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    lastTagType = LastTagType.EndTag;
                }
                else
                {
                    if (lastTagType == LastTagType.BeginTag)
                    {
                        num2++;
                    }
                    if (arrayString[i].Trim().StartsWith("__style__"))
                    {
                        arrayString[i] = css.StringFormat(arrayString[i].Replace("__style__", "").Trim(), 2);
                    }
                    else if (arrayString[i].Trim().StartsWith("__script__"))
                    {
                        arrayString[i] = CreateIndent(num * num2) + js.StringFormat(arrayString[i].Replace("__script__", "").Replace("__newline__", "\r\n").Trim(), num2);
                    }
                    else
                    {
                        arrayString[i] = CreateIndent(num * num2) + arrayString[i];
                    }
                    lastTagType = LastTagType.Text;
                }
                arrayString[i] = arrayString[i].Replace("__style__", "").Replace("__script__", "").Replace("__newline__", "");
            }
            return arrayString;
        }

        private string CreateIndent(int length)
        {
            if (length <= 0)
            {
                return "";
            }
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < length; i++)
            {
                stringBuilder.Append(" ");
            }
            return stringBuilder.ToString();
        }

        private string ConvertHtmlString(string inputString)
        {
            StringBuilder stringBuilder = new StringBuilder();
            string[] arrayString = ToFormatArray(inputString);
            arrayString = FormatImp(arrayString);
            string[] array = arrayString;
            foreach (string text in array)
            {
                stringBuilder.Append(text + "\r\n");
            }
            return stringBuilder.ToString();
        }

        public string StringFormat(string content)
        {
            string empty = string.Empty;
            try
            {
                return ConvertHtmlString(content);
            }
            catch (Exception)
            {
                return content;
            }
        }
    }
}
